package com.egreen.asset.service.Api.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.egreen.asset.dao.BalanceAccountDao;
import com.egreen.asset.dao.OperateBalanceRecordingDao;
import com.egreen.asset.dao.OperatePointRecordingDao;
import com.egreen.asset.dao.PointAccountDao;

import com.egreen.common.pojo.entity.asset.BalanceAccount;
import com.egreen.common.pojo.DTO.asset.BalanceAccountDTO;
import com.egreen.common.pojo.DTO.asset.OperateBalanceRecordingDTO;
import com.egreen.common.pojo.DTO.asset.OperatePointRecordingDTO;
import com.egreen.common.pojo.entity.asset.OperateBalanceRecording;
import com.egreen.common.pojo.entity.asset.OperatePointRecording;
import com.egreen.common.pojo.entity.asset.PointAccount;
import com.egreen.common.pojo.VO.asset.OperateBalanceRecordingVO;
import com.egreen.common.pojo.VO.asset.OperatePointRecordingVO;
import com.egreen.common.pojo.excptions.PointAccountException;
import com.egreen.common.serviceapi.asset.IAssetServiceApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Component
@DubboService
public class AssetServiceApiImpl implements IAssetServiceApi {
    @Autowired
    BalanceAccountDao balanceAccountDao;

    @Autowired
    OperateBalanceRecordingDao operateBalanceRecordingDao;

    @Autowired
    OperatePointRecordingDao operatePointRecordingDao;

    @Autowired
    PointAccountDao pointAccountDao;

    /**
     * 查询所有人的总余额
     *
     * @param
     * @return
     */
    @Override
    public BigDecimal selectTotalBalance() {
        //先查询所有的用户的余额
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("balance");
        List<BalanceAccount> list = balanceAccountDao.selectList(queryWrapper);
        //通过循环将集合中的数据相加
        BigDecimal BalanceNum = BigDecimal.valueOf(0);
        for (BalanceAccount balanceAccount : list) {
            BalanceNum = BalanceNum.add(balanceAccount.getBalance());
        }
        System.out.println(BalanceNum);
        //返回全部用户总金额
        return BalanceNum;
    }

    /**
     * 通过查找操作记录来获得已提现到支付宝的总额
     *
     * @param operate
     * @return
     */
    @Override
    public BigDecimal selectWithdrawalTotalBalance(String operate) {
        //先通过用户操作查询操作的金额
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("operate_balance_num");
        //进行筛选
        queryWrapper.eq("operate", operate);
        //根据条件查询得到数据封装到集合里
        List<OperateBalanceRecording> list = operateBalanceRecordingDao.selectList(queryWrapper);
        //通过循环将集合中的数据相加
        BigDecimal operateBalanceNum = BigDecimal.valueOf(0);
        for (OperateBalanceRecording operateBalanceRecording : list) {
            operateBalanceNum = operateBalanceNum.add(operateBalanceRecording.getOperateBalanceNum());
        }
        //返回全部用户总提现金额
        return operateBalanceNum;
    }

    /**
     * 通过账户id来单独获取余额
     *
     * @param balanceAccountId
     * @return
     */
    @Override
    public BigDecimal selectBalanceByAccountId(Long balanceAccountId) {
        //通过BalanceAccountId获取账户的余额
        BalanceAccount balanceAccount = balanceAccountDao.selectById(balanceAccountId);
        BigDecimal balance = balanceAccount.getBalance();
        return balance;
    }

    /**
     * 余额账户的建立
     *
     * @param balanceAccountDTO
     * @return
     */
    @Override
    public int addAlipayAccount(BalanceAccountDTO balanceAccountDTO) {
        BalanceAccount balanceAccount = new BalanceAccount();
        //依次插入支付宝账户id,昵称和头像
        balanceAccount.setIdentity(balanceAccountDTO.getIdentity());
        balanceAccount.setNickName(balanceAccountDTO.getNickName());
        balanceAccount.setAvatar(balanceAccountDTO.getAvatar());
        //保存到balanceAccount
        balanceAccountDao.insert(balanceAccount);
        //返回值即为id,获取id
        return balanceAccount.getId();
    }

    /**
     * 新建积分账户
     *
     * @return
     */
    @Override
    public Long addPointAccount() {
        PointAccount pointAccount = new PointAccount();
        //传入新建账户的余额
        pointAccount.setPointBalance(0);
        //将账户保存回pointAccount
        pointAccountDao.insert(pointAccount);
        //返回值即为id，直接获取id即可
        return pointAccount.getId();
    }


    /**
     * 余额增加与减少,并增加一条操作记录
     *
     * @param operateBalanceRecordingDTO
     */
    @Override
    public int updateByBalance(OperateBalanceRecordingDTO operateBalanceRecordingDTO) {
        //通过BalanceAccountId获取账户的余额
        BalanceAccount balanceAccount = balanceAccountDao.selectById(operateBalanceRecordingDTO.getBalanceAccountId());
        BigDecimal balance = balanceAccount.getBalance();

        //对用户操作进行判断并将修改后的余额传回去
        if (operateBalanceRecordingDTO.getOperate().equals("用户支付宝充值到环绿回收账户")) {
            balance = balance.add(operateBalanceRecordingDTO.getOperateBalanceNum());
        } else {
            //前者与后者比较，若前者大则返回1
            //说明减少的金额大于用户余额，所以会取不出 需要抛出异常
            if ((operateBalanceRecordingDTO.getOperateBalanceNum()).compareTo(balanceAccount.getBalance()) == 1) {
                return 0;
            } else {
                balance = balance.subtract(operateBalanceRecordingDTO.getOperateBalanceNum());
            }
        }
        //将修改后的积分余额传回去
        balanceAccount.setBalance(balance);

        //新建操作记录并修改各字段
        OperateBalanceRecording operateBalanceRecording = new OperateBalanceRecording();
        operateBalanceRecording.setBalanceAccountId(Long.valueOf(operateBalanceRecordingDTO.getBalanceAccountId()));
        operateBalanceRecording.setOperate(operateBalanceRecordingDTO.getOperate());
        operateBalanceRecording.setOperatedBalance(balance);
        operateBalanceRecording.setGenerateTradeNo(operateBalanceRecordingDTO.getGenerateTradeNo());
        operateBalanceRecording.setOperateBalanceNum(operateBalanceRecordingDTO.getOperateBalanceNum());
        operateBalanceRecording.setTime(operateBalanceRecordingDTO.getTime());

        //对操作记录进行保存
        operateBalanceRecordingDao.insert(operateBalanceRecording);

        //对操作记录进行返回更新
        return balanceAccountDao.updateById(balanceAccount);


    }

    /**
     * 通过用户ID查询余额操作记录
     *
     * @param balanceAccountId
     * @return
     */
    @Override
    public List<OperateBalanceRecordingVO> selectBalanceById(Long balanceAccountId) {
        //存放查询的条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("id", "balance_account_id", "operate", "time", "operate_balance_num", "operated_balance", "deleted");
        //进行筛选
        queryWrapper.eq("balance_account_id", balanceAccountId);
        //根据条件查询得到数据封装到集合里
        List<OperateBalanceRecordingVO> list = operateBalanceRecordingDao.selectList(queryWrapper);
        return list;
    }

    /**
     * 积分的增加与减少,并增加一条操作记录
     *
     * @param operatePointRecordingDTO
     */
    @Override
    public void updateByPoint(OperatePointRecordingDTO operatePointRecordingDTO) {//+600
        //通过pointAccountId获取账户的积分余额
        PointAccount pointAccount = pointAccountDao.selectById(operatePointRecordingDTO.getPointAccountId());
        Integer pointBalance = pointAccount.getPointBalance();

        //对用户操作进行判断
        if (operatePointRecordingDTO.getOperate().equals("增加")) {
            pointBalance = pointBalance + operatePointRecordingDTO.getOperatePointNum();
        } else {
            //前者与后者比较，若前者大则返回1
            //说明减少的积分大于用户积分余额，所以会取不出 需要抛出异常
            if ((operatePointRecordingDTO.getOperatePointNum()).compareTo(pointAccount.getPointBalance()) == 1) {
                throw new PointAccountException("积分不足");
            } else {
                pointBalance = pointBalance - operatePointRecordingDTO.getOperatePointNum();
            }
        }

        //将修改后的积分余额传回去
        pointAccount.setPointBalance(pointBalance);

        //新建操作记录并修改各字段
        OperatePointRecording operatePointRecording = new OperatePointRecording();
        operatePointRecording.setId(operatePointRecordingDTO.getId());
        operatePointRecording.setOperate(operatePointRecordingDTO.getOperate());
        operatePointRecording.setPointAccountId(operatePointRecordingDTO.getPointAccountId());
        operatePointRecording.setOperatedBalance(pointBalance);
        operatePointRecording.setOperatePointNum(operatePointRecordingDTO.getOperatePointNum());
        operatePointRecording.setTime(LocalDateTime.now());

        //对操作记录进行保存
        operatePointRecordingDao.insert(operatePointRecording);

        //对操作记录进行返回更新
        pointAccountDao.updateById(pointAccount);
    }


    /**
     * 通过用户ID查询积分操作记录
     *
     * @param
     */

    @Override
    public List<OperatePointRecordingVO> selectPointById(Long pointAccountId) {
        //存放查询的条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("id", "point_account_id", "operate", "time", "operate_point_num", "operated_balance", "deleted");
        //进行筛选
        queryWrapper.eq("point_account_id", pointAccountId);
        //根据条件查询得到数据封装到集合里
        List<OperatePointRecordingVO> list = operatePointRecordingDao.selectList(queryWrapper);
        return list;
    }

    /**
     * 通过ID查找到余额账户信息
     *
     * @param id
     * @return
     */
    @Override
    public BalanceAccountDTO selectBalanceAccountById(int id) {
        //通过id查询到余额账户
        BalanceAccount balanceAccount = balanceAccountDao.selectById(id);
        BalanceAccountDTO balanceAccountDTO = new BalanceAccountDTO();
        //获取余额账户的id,balance,identity,IdentityType,nickname,avatar后保存到balanceAccountDTO中,并返回
        balanceAccountDTO.setId(balanceAccount.getId());
        balanceAccountDTO.setBalance(balanceAccount.getBalance());
        balanceAccountDTO.setIdentityType(balanceAccount.getIdentityType());
        balanceAccountDTO.setIdentity(balanceAccount.getIdentity());
        balanceAccountDTO.setNickName(balanceAccount.getNickName());
        balanceAccountDTO.setAvatar(balanceAccount.getAvatar());
        return balanceAccountDTO;
    }

    /**
     * 余额账户的修改
     *
     * @param balanceAccountDTO
     */
    @Override
    public int updateAlipayAccount(BalanceAccountDTO balanceAccountDTO) {
        //通过id查找到用户的账户信息
        BalanceAccount balanceAccount = balanceAccountDao.selectById(balanceAccountDTO.getId());

        //判断是否查出了用户信息,不为空即为查出来账户信息了
        if (balanceAccount != null) {
            //如果用户存在的话，可以进行修改操作
            balanceAccount.setId(balanceAccountDTO.getId());
            balanceAccount.setIdentity(balanceAccountDTO.getIdentity());
            balanceAccount.setNickName(balanceAccountDTO.getNickName());
            balanceAccount.setAvatar(balanceAccountDTO.getAvatar());
            balanceAccountDao.updateById(balanceAccount);
        } else {
            //抛出异常
        }
        return balanceAccountDao.updateById(balanceAccount);
    }

    @Override
    public long addBalanceAccount() {
        BalanceAccount balanceAccount = new BalanceAccount();
        //传入新建账户的余额
        BigDecimal a = new BigDecimal(0);
        balanceAccount.setBalance(a);
        //将账户保存回pointAccount
        balanceAccountDao.insert(balanceAccount);
        //返回值即为id，直接获取id即可
        return balanceAccount.getId();
    }

    /**
     * 通过 AccountId查询用户积分
     *
     * @param pointAccountId
     * @return
     */
    @Override
    public Integer selectPointByAccountId(Long pointAccountId) {
        PointAccount pointAccount = pointAccountDao.selectById(pointAccountId);
        Integer Point = pointAccount.getPointBalance();
        return Point;
    }

    /**
     * 终端换产生的交易改变余额账户余额并生成一条余额交易记录
     *
     * @param userID
     * @param trandMoney
     */
    @Override
    public void userBalanceChange(String userID, String trandMoney) {
        BigDecimal tm = new BigDecimal(trandMoney);
        BalanceAccount balanceAccount = balanceAccountDao.selectById(userID);
        BigDecimal balance = balanceAccount.getBalance();
        //将账户余额加交易金额得到更改后的余额
        BigDecimal modifiedBalance = balanceAccount.getBalance().add(tm);
        balanceAccount.setBalance(modifiedBalance);

        int updateNum = balanceAccountDao.updateById(balanceAccount);
        if (updateNum == 1) {
            OperateBalanceRecording operateBalanceRecording = new OperateBalanceRecording();
            operateBalanceRecording.setId(Integer.valueOf(userID));
            operateBalanceRecording.setBalanceAccountId(Long.valueOf(balanceAccount.getId()));
            operateBalanceRecording.setOperate("用户进行终端交易产生收益");
            operateBalanceRecording.setTime(LocalDateTime.now());
            operateBalanceRecording.setOperateBalanceNum(new BigDecimal(trandMoney));
            operateBalanceRecording.setOperatedBalance(modifiedBalance);
            operateBalanceRecording.setGenerateTradeNo(generateTradeNo());

            operateBalanceRecordingDao.insert(operateBalanceRecording);
        }

    }


    /**
     * @return
     */
    private String generateTradeNo() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String tradeNo = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
        log.info("终端交易产生的内部订单号:{}", tradeNo);
        return tradeNo;
    }

}


